import * as THREE from "../../../modules/three/three.module.js";
import { flatten } from '../lib/util/StaticMethods.js';
import World3dEvent from '../scene/event/World3dEvent.js';
import PluginBase from './PluginBase.js';

export default class SelectFixedEyePlugin extends PluginBase {
  world3d;
  _camera;
  _cameraHelper;
  _selectMesh;
  fixedEye;

  constructor(world3d) {
    super();
    this.world3d = world3d;
    this._camera = new THREE.PerspectiveCamera().copy(
      this.world3d._perspCamera,
    );
    this._cameraHelper = new THREE.CameraHelper(this._camera);
  }

  /**
   *
   * @param {EyeIndicator} eyeIndicator
   */
  attachItem(eyeIndicator) {
    this.fixedEye = eyeIndicator;
    this._camera.position.copy(eyeIndicator.position);
    this._camera.lookAt(eyeIndicator.focus);
    this._camera.updateMatrixWorld(true);
    this._camera.updateProjectionMatrix();
    this.world3d.scene.add(this._cameraHelper);
    if (!this._selectMesh) {
      const { index, vectors } = eyeIndicator.geometryInfo;
      const geometry = new THREE.BufferGeometry();
      geometry.setIndex(index);
      geometry.setAttribute(
        'position',
        new THREE.BufferAttribute(flatten(vectors), 3),
      );
      this._selectMesh = new THREE.Mesh(
        geometry,
        new THREE.MeshBasicMaterial({
          color: '#bb0',
          transparent: true,
          opacity: 0.5,
        }),
      );
    }
    this._selectMesh.position.copy(eyeIndicator.position);
    this._selectMesh.quaternion.copy(eyeIndicator.quaternion);
    this.world3d.scene.add(this._selectMesh);
  }

  detachItem() {
    if (!this.fixedEye) {
      return;
    }
    this._cameraHelper.removeFromParent();
    this._selectMesh.removeFromParent();
    this.fixedEye = null;
  }

  detachIfNeed(eyeObj) {
    if (this.fixedEye && this.fixedEye.dataObj.id === eyeObj.id) {
      this.detachItem();
    }
  }

  pointerDown(event) {
    if (event.button === 2) {
      // mouse right button down
      return;
    }
    const store = this.world3d.store;
    if (store.stateAddingFixedEye || store.stateAddingSampleCubeVert) {
      return;
    }
    const eyeIndicator = store.pickingEyeIndicator();
    if (eyeIndicator) {
      this.attachItem(eyeIndicator);
      const evt = World3dEvent.eyeIndicatorSelected;
      evt.value.pos.copy(eyeIndicator.position);
      evt.value.target.copy(eyeIndicator.focus);
      evt.value.distance = eyeIndicator.getDist();
      evt.value.id = eyeIndicator.dataObj.id;
      this.world3d.scene.dispatchEvent(evt);
    }
  }
}
